/*
 * @Author: complex 1944755442@qq.com
 * @Date: 2024-01-24 16:35:33
 * @LastEditors: complex 1944755442@qq.com
 * @LastEditTime: 2024-01-25 17:51:23
 * @FilePath: /prjs/my-linux-snake/debugLog.c
 * @Description: 调试信息的打印，一方面可以用va_list 自定义调试，另外一方面也可以用宏定义
 * 第一种方法：灵活度高，容易编写复杂的式子。参数检查逻辑明确（输出流的NULL判断），但是好像不能打印出__FILE__, __LINE__的信息。因为打印出来的是在函数中的。
 * 第二种方法：容易编写简单的式子。参数检查逻辑不明确。能够直接输出__FILE__,__LINE__信息.
 */
#include <stdio.h>
#include "debugLog.h"

FILE *log_fp;
void debug_file_init()
{
    log_fp = fopen(DEBUG_FILE, "a");
    if(log_fp == NULL)
    {
        perror("LOG_FILE cannot open!");
        exit(-1);
    }
}


void debug_timestamp()
{
    time_t timesec = time(NULL);
    char *curtime = ctime(&timesec);
	
	#ifdef FILE_DEBUG_MODE
		FILE *fp = log_fp;
	#else
		FILE *fp = stderr;
	#endif

	fprintf(fp,"<TimeStamp>: %s", curtime);
}

//第一步：创建变参函数需要包含头文件 stdarg.h 并且定义一个使用省略号的函数原型
int FILE_DEBUG_PRINTF(const char*format, ...) //char*format = "%d%s\n"
{
#ifdef FILE_DEBUG_MODE //表示将输出信息 输出到文本中
	FILE *fp = log_fp;
	if(fp == NULL)
	{
		printf("请先调用initLog 初始化......\n");
		return -1;
	}
#else  //否则输出到屏幕终端
	fp = stderr;
#endif	
	time_t timesec = time(NULL);
    char *curtime = ctime(&timesec);
	fprintf(fp, "\n\n<Current Time>:%s", curtime);

	fprintf(fp, "<Debug Info>:\n");
	//想办法获取 实参传递过来的数据 
	int i = 0;
	
	//第二步：在函数定义中创建一个va_list 类型的变量，用于存储那些不固定的参数  (variable argument)
	va_list va; //存储 从 外面传递过来的实参的数据
	
	//第三步：调用 va_start() 使得va存放变参函数的变参前的一个固定参数的地址；
	va_start(va,format);
	
	//第四步：不断地调用va_arg()使得va指向下一个实参，该宏函数也会返回实参的值
	while(format[i] != '\0')
	{
		if(format[i] == '%' && format[i+1] == 'd')
		{
			
			fprintf(fp,"%d",va_arg(va,int)); //va_arg 该函数可以帮助我们获取 数据
			i++;
		}
		else if(format[i] == '%' && format[i+1] == 'f')
		{
			fprintf(fp,"%f",va_arg(va,double)); //va_arg 该函数可以帮助我们获取 数据
			i++;
		}
		else if(format[i] == '%' && format[i+1] == 's')
		{
			fprintf(fp,"%s",va_arg(va,char*)); //va_arg 该函数可以帮助我们获取 数据
			i++;
		}else{
			fprintf(fp,"%c",format[i]); //va_arg 该函数可以帮助我们获取 数据
		}
		
		i++;
	}
	
	//第五步：最后调用va_end()表示变参处理完成，将va置空
	va_end(va);
}



